﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using iStudio.Engine;
using CSCore;
using CSCore.Codecs;
using CSCore.Codecs.WAV;
using CSCore.Streams;

namespace iStudio.Test
{
    [TestClass]
    public class BlockFileTest
    {
        const string testblockfile = @"C:\Temp\test.blockfile";
        const string mp3testfile = @"C:\Temp\test.mp3";
        const string dumptestfile = @"C:\Temp\dump.wav";

        [TestMethod]
        [TestCategory("Engine")]
        public void BlockFileChannelReadWriteTest()
        {
            ResetTestFile();
            var source = new SineGenerator();//CodecFactory.Instance.GetCodec(mp3testfile).ToSampleSource();
            BlockFileHeader header = new BlockFileHeader()
            {
                Channels = 2,
                Encoding = BlockFileEncoding.IeeeFloat32,
                SampleRate = source.WaveFormat.SampleRate
            };

            BlockFile blockFile = BlockFile.CreateNew(testblockfile, header);
            BlockFileChannel blockFileChannel = new BlockFileChannel(blockFile, 0);
            BlockFileChannel blockFileChannel1 = new BlockFileChannel(blockFile, 1);

            float[] buffer = new float[source.WaveFormat.Channels * 5000];
            for (int i = 0; i < 300; i++)
            {
                int read = source.Read(buffer, 0, buffer.Length);
                blockFileChannel.Write(buffer, 0, read);
            }

            blockFileChannel1.Position = 0 * 5000; ;
            source = new SineGenerator(100, 0.8, -1);
            for (int i = 0; i < 500; i++)
            {
                int read = source.Read(buffer, 0, buffer.Length);
                blockFileChannel1.Write(buffer, 0, read);
            }

            //--- write to dump file

            WaveWriter writer = new WaveWriter(dumptestfile, new CSCore.WaveFormat(header.SampleRate, 32, blockFile.Channels, CSCore.AudioEncoding.IeeeFloat));
            blockFile.Position = 0;


            int read1 = 0;
            while ((read1 = blockFile.Read(buffer, 0, buffer.Length)) > 0)
            {
                writer.WriteSamples(buffer, 0, read1);
            }

            writer.Dispose();
            blockFile.Dispose();
            source.Dispose();
        }

        [TestMethod]
        [TestCategory("Engine")]
        public void BlockFileChannelWriteTest()
        {
            ResetTestFile();
            var source = CodecFactory.Instance.GetCodec(mp3testfile).ToSampleSource();
            BlockFileHeader header = new BlockFileHeader()
            {
                Channels = source.WaveFormat.Channels,
                Encoding = BlockFileEncoding.IeeeFloat32,
                SampleRate = source.WaveFormat.SampleRate
            };

            BlockFile blockFile = BlockFile.CreateNew(testblockfile, header);
            float[] buffer = new float[source.WaveFormat.Channels * 5000];
            for (int i = 0; i < 500; i++)
            {
                int read = source.Read(buffer, 0, buffer.Length);
                blockFile.Write(buffer, 0, read);
            }

            //---

            WaveWriter writer = new WaveWriter(dumptestfile, new CSCore.WaveFormat(header.SampleRate, 32, 1, CSCore.AudioEncoding.IeeeFloat));
            blockFile.Position = 0;

            var blockFileChannel = new BlockFileChannel(blockFile, 0);

            int read1 = 0;
            while ((read1 = blockFileChannel.Read(buffer, 0, buffer.Length)) > 0)
            {
                writer.WriteSamples(buffer, 0, read1);
            }

            writer.Dispose();
            blockFile.Dispose();
            source.Dispose();
        }

        [TestMethod]
        [TestCategory("Engine")]
        public void BasicBlockFileReadWriteTest()
        {
            ResetTestFile();
            SineGenerator sine = new SineGenerator(1000, 0.8, 0);
            BlockFileHeader header = new BlockFileHeader()
            {
                Channels = sine.WaveFormat.Channels,
                Encoding = BlockFileEncoding.IeeeFloat32,
                SampleRate = sine.WaveFormat.SampleRate
            };
            
            BlockFile blockFile = BlockFile.CreateNew(testblockfile, header);
            float[] buffer = new float[sine.WaveFormat.Channels * 5000];
            for (int i = 0; i < 1000; i++)
            {
                int read = sine.Read(buffer, 0, buffer.Length);
                blockFile.Write(buffer, 0, read);
            }

            WaveWriter writer = new WaveWriter(dumptestfile, new CSCore.WaveFormat(header.SampleRate, 32, header.Channels, CSCore.AudioEncoding.IeeeFloat));
            blockFile.Position = 0;

            int read1 = 0;
            while ((read1 = blockFile.Read(buffer, 0, buffer.Length)) > 0)
            {
                writer.WriteSamples(buffer, 0, read1);
            }

            writer.Dispose();
            blockFile.Dispose();
            sine.Dispose();
        }

        [TestMethod]
        [TestCategory("Engine")]
        public void BasicBlockFileTest()
        {
            ResetTestFile();
            BlockFileHeader header = new BlockFileHeader()
            {
                Channels = 5,
                DataOffset = 500,
                Encoding = BlockFileEncoding.IeeeFloat32,
                Reserved = -1,
                SampleRate = 44100
            };

            using (BlockFile blockFile = BlockFile.CreateNew(testblockfile, header))
            {
            }

            using (var blockFile1 = BlockFile.Open(testblockfile))
            {
                if (!blockFile1.Header.Equals(header))
                    throw new Exception("BlockFileHeader");
            }
        }

        private void ResetTestFile()
        {
            if (System.IO.File.Exists(testblockfile))
                System.IO.File.Delete(testblockfile);
        }
    }
}
